#ifndef __PACKETHEADER_H__
#define __PACKETHEADER_H__

#include "OSHeaders.h"
#include <string.h>

//byte bound
#pragma pack(1)
struct CDNPacketHeader {
	UInt16		Length;
	//type
	enum {MCDMS=1,MRBS=2,MRFSS=3,MFT=4};
	char			Type[2];
	UInt32		ID;
	//directary
	enum {REQUEST=1,RESPONSE=2,SINGLE=3};
	UInt8			Dir;
	UInt16		Cmd;
	//error code
	enum {NoErr=0, Err=-1};
	Int8			ErrCode;
};
#pragma pack()
//restore to deault value.

#define MAKETYPE(Type,Header) {	\
	switch(Type)	\
	{	\
		case CDNPacketHeader::MCDMS: \
			Header.Type[0] ='C';Header.Type[1] ='D'; break;	\
		case CDNPacketHeader::MRBS: \
			Header.Type[0] ='R';Header.Type[1] ='B'; break;	\
		case CDNPacketHeader::MRFSS: \
			Header.Type[0] ='R';Header.Type[1] ='F'; break;	\
		case CDNPacketHeader::MFT: \
			Header.Type[0] ='F';Header.Type[1] ='T'; break;	\
	}\
}

class ParserCDNPacket {
private:
	char *m_pStr;
public:	
	ParserCDNPacket(char *vStr) 	{m_pStr = vStr;}
	UInt16	GetLength() 				{return *(UInt16 *)m_pStr;}
	void 		GetType( char *vStr)	{vStr[0] = m_pStr[2]; vStr[1] = m_pStr[3];}
	UInt32	GetID()						{return *(UInt32 *)(m_pStr	+4);}
	UInt8		GetDir()						{return (UInt8)(m_pStr[8]);}
	UInt16	GetCmd()					{return *(UInt16 *)(m_pStr +9);}
	Int8		GetErrCode()				{return m_pStr[11];}
};

class PackCDNPacket {
	CDNPacketHeader m_Header;
public:
	PackCDNPacket()	 					{::memset(&m_Header,0,sizeof(CDNPacketHeader));}
	PackCDNPacket(const char *vStr)	 	{if(vStr) ::memcpy((char *)&m_Header,vStr,sizeof(CDNPacketHeader));}	//copy
	void Assign(const char *vStr)			{if(vStr) ::memcpy((char *)&m_Header,vStr,sizeof(CDNPacketHeader));}	//copy
	void SetLength(UInt16 vLen)		{m_Header.Length = vLen;}
	void SetType(UInt8 Type)			{MAKETYPE(Type,m_Header);}
	void SetType(const char *vStr)			{if(vStr){m_Header.Type[0] = vStr[0];m_Header.Type[1] = vStr[1];}}
	void SetID(UInt32 vID)			{m_Header.ID = vID;}
	void SetDir(UInt8 vDir)				{m_Header.Dir = vDir;}
	void SetCmd(UInt16 vCmd)		{m_Header.Cmd = vCmd;}
	void SetErrCode(Int8 vErrcode)	{m_Header.ErrCode = vErrcode;}
	CDNPacketHeader * GetCDNPacket()	{return &m_Header;}
	UInt16	GetLength()					{return sizeof(CDNPacketHeader);}
};
#endif

